package edu.pku.sei.mte.mtemodel.model;

import edu.pku.sei.mte.mtemodel.core.DataType;
import edu.pku.sei.mte.mtemodel.core.Element;
import edu.pku.sei.mte.mtemodel.core.NamedElement;
import edu.pku.sei.mte.mtemodel.core.TypedElement;
import edu.pku.sei.mte.mtemodel.graph.GraphObject;
import edu.pku.sei.mte.utilities.Visitor;

public class MAttribute extends Element implements NamedElement, TypedElement {
	private String name;
	private DataType type;
	private Object value;
	private boolean locked;
	
	private AttributedElement host;

	public String getName() {
		return this.name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public DataType getType() {
		return type;
	}

	public void setType(DataType type) {
		this.type = type;
	}

	public Object getValue() {
		return value;
	}

	@SuppressWarnings("unchecked")
	public void setValue(Object value){
		Object oldValue = this.value;
		this.value = value;
		if((oldValue==null&&value!=null)||(oldValue!=null&&!oldValue.equals(value))){
			if(this.getHost()!=null&&this.getHost() instanceof GraphObject){
				GraphObject host = (GraphObject)this.getHost();
				if(host.getHost()!=null)
					host.getHost().notifyObjectModification(host);
			}
		}
	}

	public AttributedElement getHost() {
		return host;
	}

	protected void setHost(AttributedElement host) {
		this.host = host;
	}
	
	public boolean equals(Object value){
		if(this.value!=null&&this.value.equals(value))
				return true;
		else return super.equals(value);
	}

	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append(name);
		builder.append('@');
		builder.append(type);
		builder.append('=');
		builder.append(value);
		return builder.toString();
	}

	public boolean isLocked() {
		return locked;
	}

	public void setLocked(boolean locked) {
		this.locked = locked;
	}

	@Override
	public Object accept(Visitor visitor) {
		return visitor.visitMAttribute(this);
	}
}
